package com.publish.file.handler;

import java.util.Iterator;

import javax.validation.ConstraintViolation;
import javax.validation.ConstraintViolationException;

import org.springframework.security.access.AccessDeniedException;
import org.springframework.web.bind.MethodArgumentNotValidException;
import org.springframework.web.bind.MissingServletRequestParameterException;
import org.springframework.web.bind.annotation.ExceptionHandler;
import org.springframework.web.bind.annotation.RestControllerAdvice;

import com.publish.file.controller.Result;

/**
 * 
 * @author hxx 全局参数异常捕获处理 该异常只捕获请求数据类型为json
 * 
 *         需要加一个判断 读取全局属性，当为debug的时候显示详细错误信息，当为正式版本则显示简略信息，防止被攻击
 */
@RestControllerAdvice
public class HttpExceptionHandler {
	/**
	 * 请求体为json的
	 * 
	 * @param exception
	 * @return
	 */
	@ExceptionHandler(MethodArgumentNotValidException.class)
	public String handleParamInvalid(MethodArgumentNotValidException exception) {
		return exception.getBindingResult().getFieldError().getDefaultMessage();
	}

	/**
	 * 参数缺失，未传指定参数
	 * 
	 * @param exception
	 * @return
	 */
	@ExceptionHandler(MissingServletRequestParameterException.class)
	public Result<String> handleParamMissing(MissingServletRequestParameterException exception) {
		String paramNameString = exception.getParameterName();
		String typeString = exception.getParameterType();
		return Result.fail(Result.CODE_REQUEST, String.format("缺少指定参数:%s,类型为:%s", paramNameString, typeString));
	}

	/**
	 * 请求参数不符合约束
	 * 
	 * @param exception
	 * @return
	 */
	@ExceptionHandler(ConstraintViolationException.class)
	public Result<String> constraintException(ConstraintViolationException exception) {
		for (Iterator<ConstraintViolation<?>> iterator = exception.getConstraintViolations().iterator(); iterator
				.hasNext();) {
			ConstraintViolation<?> constraintViolation = iterator.next();
			return Result.fail(Result.CODE_REQUEST, constraintViolation.getMessage());
		}
		return Result.fail(Result.CODE_AUTH_DENIED, Result.CODE_AUTH_DENIED_STRING);
	}

	/**
	 * 访问无权限的资源
	 * 
	 * @param exception
	 * @return
	 */
	@ExceptionHandler(AccessDeniedException.class)
	public Result<String> handleAccessDeniedException(AccessDeniedException exception) {
		return Result.fail(Result.CODE_AUTH_DENIED, Result.CODE_AUTH_DENIED_STRING);
	}
}
